package cn.demoncat.util.sec;

import cn.demoncat.util.lang.msg.SecMsg;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

/**
 * 描述：HmacSHA1 消息摘要 （数据唯一签名，不可逆）
 * <br/>
 * <br/>
 * MAC算法：结合MD5和SHA的优势，加入密钥元素，是更安全的消息摘要算法
 *
 * @author 延晓磊
 *
 * @since 2016年8月11日
 */
public class HmacSHA1Util extends SecurityUtil{

	/**
	 * 加密算法
	 */
	public static final String ALGORITHM = "HmacSHA1";
	
	
	/**
	 * 生成密钥
	 * 
	 * @param keyCode	KEY_CODE
	 * @return 密钥
	 * 
	 * @author 延晓磊
	 *
	 * @since 2016年8月11日
	 */
	public static byte[] getKey(String keyCode) {
		try {
			// 实例化密钥生成器
			KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);
			// SHA1密码随机数供应者
			SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
			secureRandom.setSeed(keyCode.getBytes(StandardCharsets.UTF_8));
			// 初始化
			kg.init(secureRandom);
			// 生成秘密密钥
			SecretKey secretKey = kg.generateKey();
			// 获得密钥的二进制编码形式
			return secretKey.getEncoded();
		} catch (Exception e) {
			throw new RuntimeException(SecMsg.ERROR_KEYCODE,e);
		}
	}
 
	/**
	 * HmacSHA1 签名
	 * 
	 * @param data		源数据
	 * @param keyCode	KEY_CODE
	 * @return 数据签名 (40位16进制字符串)
	 * 
	 * @author 延晓磊
	 *
	 * @since 2016年8月11日
	 */
	public static String digest(byte[] data, String keyCode) {
		try {
			// 还原密钥
			SecretKey secretKey = new SecretKeySpec(getKey(keyCode), ALGORITHM);
			// 实例化Mac
			Mac mac = Mac.getInstance(secretKey.getAlgorithm());
			// 初始化密钥
			mac.init(secretKey);
			// 执行消息摘要
			return HexUtil.encode(mac.doFinal(data));
		} catch (Exception e) {
			throw new RuntimeException(SecMsg.ERROR_KEYCODE,e);
		}
	}

	/**
	 * HmacSHA1 签名
	 * 
	 * @param data		源数据
	 * @param keyCode	KEY_CODE
	 * @return 数据签名 (40位16进制字符串)
	 * 
	 * @author 延晓磊
	 *
	 * @since 2016年8月11日
	 */
	public static String digest(String data, String keyCode) {
		try {
			// 还原密钥
			SecretKey secretKey = new SecretKeySpec(getKey(keyCode), ALGORITHM);
			// 实例化Mac
			Mac mac = Mac.getInstance(secretKey.getAlgorithm());
			// 初始化密钥
			mac.init(secretKey);
			// 执行消息摘要
			return HexUtil.encode(mac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
		} catch (Exception e) {
			throw new RuntimeException(SecMsg.ERROR_KEYCODE,e);
		}
	}
}
